using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Services.Protocols;
using System.IO;

namespace GetTogether.Studio.WebService.Extension
{
    public class SoapMessageAccessClientExtension : SoapExtension
    {
        Stream oldStream = null;
        Stream newStream = null;

        public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
        {
            return null;
        }

        public override object GetInitializer(Type t)
        {
            return typeof(SoapMessageAccessClientExtension);
        }

        public override void Initialize(object initializer)
        {
            
        }

        public override void ProcessMessage(SoapMessage message)
        {
            switch (message.Stage)
            {
                case SoapMessageStage.BeforeSerialize:
                    break;

                case SoapMessageStage.AfterSerialize:
                    StoreRequestMessage(message);
                    Copy(newStream, oldStream);
                    break;

                case SoapMessageStage.BeforeDeserialize:
                    StoreResponseMessage(message);
                    break;

                case SoapMessageStage.AfterDeserialize:
                    break;

                default:
                    throw new ArgumentException("Invalid Soap Message stage [" + message.Stage + "]", "message");
            }
        }

        public override Stream ChainStream(Stream stream)
        {
            oldStream = stream;
            newStream = new MemoryStream();
            return newStream;
        }

        private void StoreRequestMessage(SoapMessage message)
        {
            newStream.Position = 0;
            byte[] bufEncSoap = new Byte[newStream.Length];
            newStream.Read(bufEncSoap, 0, bufEncSoap.Length);
            ((SoapHttpClientProtocolExtension)(((SoapClientMessage)message).Client)).SoapRequest = bufEncSoap;
        }

        private void StoreResponseMessage(SoapMessage message)
        {
            Stream tempStream = new MemoryStream();
            Copy(oldStream, tempStream);
            byte[] bufEncSoap = new Byte[tempStream.Length];
            tempStream.Read(bufEncSoap, 0, bufEncSoap.Length);
            ((SoapHttpClientProtocolExtension)(((SoapClientMessage)message).Client)).SoapResponse = bufEncSoap;
            Copy(tempStream, newStream);
        }

        void Copy(Stream from, Stream to)
        {
            if (from.CanSeek == true)
                from.Position = 0;
            TextReader reader = new StreamReader(from);
            TextWriter writer = new StreamWriter(to);
            writer.WriteLine(reader.ReadToEnd());
            writer.Flush();
            if (to.CanSeek == true)
                to.Position = 0;
        }
    }
}